<?php

namespace GordenSong\Console\Command;

use Doctrine\DBAL\Schema\SchemaException;
use GordenSong\Exceptions\BladeFileNotFoundException;
use GordenSong\Exceptions\FilePutContentException;
use GordenSong\Exceptions\TableNotExistException;
use GordenSong\Exceptions\TargetFileExistsException;
use GordenSong\Templates\TableValidatorCacheTemplate;
use GordenSong\Utils\DatabaseUtil;
use Illuminate\Filesystem\Filesystem;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;

class GenerateTableValidatorCacheCommand extends \Illuminate\Console\Command
{
	/**
	 * @var Filesystem $files
	 */
	protected $files;

	/**
	 * The console command name.
	 *
	 * @var string
	 */
	protected $name = 'validator:cache {connection} {--delete}';

	/**
	 * @var string
	 */
	protected $dir = 'app';

	/**
	 * The console command description.
	 *
	 * @var string
	 */
	protected $description = 'Generate one or more table validator cache';

	/**
	 * @var string
	 */
	protected $existingFactories = '';

	/**
	 * @var array
	 */
	protected $properties = [];

	/**
	 * @var
	 */
	protected $delete;
	/**
	 * @var
	 */
	protected $partial;
	/**
	 * @var string
	 */
	private $connection;

	/**
	 * @param Filesystem $files
	 */
	public function __construct(Filesystem $files)
	{
		parent::__construct();
		$this->files = $files;
	}

	/**
	 * Execute the console command.
	 *
	 * @return void
	 */
	public function handle()
	{
//		$this->dir = $this->option('dir');
		$this->delete = $this->option('delete');
		$this->connection = $this->argument('connection') ?: config('database.default');

		$tableNames = DatabaseUtil::allTableNames($this->connection, false);
		if (count($tableNames) == 0) {
			$this->warn('has no table');
			return;
		}

		foreach ($tableNames as $tableName) {
			if ($tableName === 'migrations') {
				continue;
			}

			$cacheTemplate = new TableValidatorCacheTemplate($this->connection, $tableName);
			try {
				$cacheTemplate->getCompiledData();
			} catch (TableNotExistException | SchemaException $e) {
				$this->error($e->getMessage());
				continue;
			}

			$filename = $cacheTemplate->targetFile();
			if ($this->delete) {
				if (!$this->files->exists($filename)) {
					$this->info("connection({$this->connection}) validator cache don't exists." . $filename);
					continue;
				}
				if ($this->files->delete($filename)) {
					$this->info("connection({$this->connection}) validator cache has been deleted, " . $filename);
				} else {
					$this->warn("connection({$this->connection}) validator cache deleted fail " . $filename);
				}
				continue;
			}

			try {
				$cacheTemplate->output(true);
				$this->info("connection({$this->connection}) validator cache has been created." . $filename);
			} catch (TargetFileExistsException | BladeFileNotFoundException | FilePutContentException  $e) {
				$this->error($e->getMessage());
			}
		}
	}

	/**
	 * Get the console command arguments.
	 *
	 * @return array
	 */
	protected function getArguments(): array
	{
		return [
			['connection', InputArgument::REQUIRED | InputArgument::OPTIONAL, 'Which connection to cache', []],
		];
	}

	/**
	 * Get the console command options.
	 *
	 * @return array
	 */
	protected function getOptions(): array
	{
		return [
//			['dir', 'D', InputOption::VALUE_OPTIONAL, 'The validator directory', $this->dir],
			['delete', 'd', InputOption::VALUE_NONE, 'delete any existing validator cache'],
		];
	}
}
